package com.ball.dev.service.impl;


import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ball.common.dtos.ResponseResult;
import com.ball.common.enums.AppHttpCodeEnum;
import com.ball.common.utils.*;
import com.ball.dev.entity.dto.LoginDto;
import com.ball.dev.entity.po.AppUser;
import com.ball.dev.entity.po.Personal;
import com.ball.dev.mapper.AppUserMapper;
import com.ball.dev.service.IAppUserService;
import com.ball.dev.service.IPersonalService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;

import java.io.IOException;
import java.io.InputStreamReader;

import java.net.*;

import java.io.BufferedReader;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Objects;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author lou
 * @since 2023-11-25
 */
@Service
@Data
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements IAppUserService {

    @Autowired
    private  IPersonalService personalService;

    @Autowired
    private RestTemplate restTemplate;
    private  String appId;
    private  String appSecret;

    public AppUserServiceImpl(@Value("${wechat.app-id}") String appId,
                                 @Value("${wechat.app-secret}") String appSecret) {
        this.appId = appId;
        this.appSecret = appSecret;
    }


    public ResponseResult WXLogin(String jsCode) throws MalformedURLException {
        // 调用微信接口获取openid和session_key
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session"
                + "?appid=" + appId
                + "&secret=" + appSecret
                + "&js_code=" + jsCode
                + "&grant_type=authorization_code";

//        // 发送HTTP请求并解析响应内容
//        // 这里假设使用了RestTemplate或者OkHttp之类的工具类
////        ResponseEntity<String> response = restTemplate.getForEntity(requestUrl, String.class);
//        String body = HttpRequest.get(requestUrl).execute().body();
//
//        // 解析响应json，获取openid等信息
//        JSONObject jsonObject = JSON.parseObject(body);
//        String openid = jsonObject.getString("openid");
//        String sessionKey = jsonObject.getString("session_key");

       try {

            // 创建一个URL对象，它表示要发送请求的URL
            URL url = new URL(requestUrl);

            // 打开一个HttpURLConnection对象，它表示一个到给定URL的连接
            HttpURLConnection connection = null;
            connection = (HttpURLConnection) url.openConnection();


            // 设置请求方式
            connection.setRequestMethod("GET");

            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");


            // 获取响应码
            int responseCode = connection.getResponseCode();

            String openid = null;
            if (responseCode == HttpURLConnection.HTTP_OK) {

                // 创建一个BufferedReader对象，它表示一个可以读取URL输入流的对象
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));

                // 创建一个StringBuilder对象，用于存储响应
                StringBuilder response = new StringBuilder();

                // 创建一个StringBuilder对象，用于存储响应
                String inputLine;

                // 循环读取响应
                while ((inputLine = in.readLine()) != null) {

                    // 将响应添加到StringBuilder对象中
                    response.append(inputLine);

                }

                // 关闭输入流
                in.close();
                // 将StringBuilder对象转换为String对象
                String jsonResponse = response.toString();
                // 将String对象转换为JSONObject对象
                JSONObject jsonObject = JSON.parseObject(jsonResponse);
                // 从JSONObject对象中获取openid
                openid = jsonObject.getString("openid");
            }


            // 使用openid关联或创建用户，然后生成并返回token
            AppUser user = lambdaQuery().eq(AppUser::getOpenid, openid)
                    .one(); // 假设有一个服务方法用来获取或创建用户

            if (user == null) {
                // 添加用户 将添加的信息存入到数据库中
                user = new AppUser();
                user.setOpenid(openid);
                user.setCreateTime(LocalDateTime.now());
                user.setUpdateTime(LocalDateTime.now());
                save(user);

                Personal personal = new Personal();
                personal.setUserId(user.getId().toString());
                personal.setUserName("用户 " + SaltUtils.getNameSuffix8());
                personal.setPhoto("https://basketball-11.oss-cn-beijing.aliyuncs.com/43f1fdbcd5ff4b87ab86d62d7e0fbb53.jpeg");
                personal.setCreateTime(LocalDateTime.now());
                personalService.save(personal);


            }
            //封装token
            HashMap<String, Object> map = new HashMap<>();
            //将token封装到map中
            map.put("token", AppJwtUtil.getToken(user.getId().toString()));

            //将密码、和salt设置为空、避免泄露

            map.put("userid", user.getId().toString());

            //将map返回到前端
            return ResponseResult.okResult(map);
        } catch (ProtocolException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }



    /**
 * 用户登录。
 *
 * @param dto 包含账号和密码的登录数据传输对象。
 * @return 返回登录结果，如果成功，包含token和用户信息；如果失败，返回错误信息。
 */
@Override
public ResponseResult loginUser(LoginDto dto) {
    // 检查输入的登录数据是否为空
    if (dto == null)
        return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "请先输入账号密码");

    // 检查账号是否为空
    if (StringUtils.isBlank(dto.getAccount()))
        return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "请先输入账号");
    // 检查密码是否为空
    if (StringUtils.isBlank(dto.getPassword()))
        return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "请先输入密码");

    // 去除账号和密码中的空格
    String account = dto.getAccount().replaceAll(" +", "");
    String password = dto.getPassword().replaceAll(" +", "");
    dto.setAccount(account);
    dto.setPassword(password);

    // 查询数据库中是否存在该账号
    AppUser user = lambdaQuery()
            .eq(AppUser::getAccount, dto.getAccount())
            .eq(AppUser::getPassword, dto.getPassword())
            .eq(AppUser::getStatus,0)
            .one();
    if (user == null) {
        return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "账号错误或者密码错误");
    }


    if (user.getManageStatus() !=1){
        return ResponseResult.errorResult(AppHttpCodeEnum.NEED_ADMIND);
    }
    // 准备登录成功后的返回数据
    HashMap<String, Object> map = new HashMap<>();
    map.put("token", AppJwtUtil.getToken(user.getId()));

    // 清除密码和盐值信息，避免敏感信息泄露
    user.setPassword("");
    user.setSalt("");
    map.put("user", user);

    return ResponseResult.okResult(map);
}


    @Override
    public ResponseResult UserRegister(LoginDto dto) {
        //判断数据是否为空
        if (dto == null ) return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"请先输入账号密码");

        //判断账号是否为空
        if (StringUtils.isBlank(dto.getAccount())) return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"请先输入账号");
        //判断密码是否为空
        if (StringUtils.isBlank(dto.getPassword())) return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"请先输入密码");

        //去除账号密码的空格
        String account = dto.getAccount().replaceAll(" +", "");
        String password = dto.getPassword().replaceAll(" +", "");
        dto.setAccount(account);
        dto.setPassword(password);
        AppUser one = lambdaQuery().eq(AppUser::getAccount, dto.getAccount()).one();

        if (one != null) return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST,"不能重复注册");

        //长度
        if (!(account.length()>=6) || !(account.length() <= 15) )
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"长度要在6-15位");

        //校验账号是否符合标准
        if (!ValidatorUtils.validateAccount(account)){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"账号只能有数字和字母");
        }
        //校验密码是否符合标准
        if (!ValidatorUtils.validatePassword(password)){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"密码至少有字母、数字、符号中的两种类型");
        }

        AppUser register = BeanUtils.copyBean(dto, AppUser.class);

        register.setCreateTime(LocalDateTime.now());
        register.setUpdateTime(LocalDateTime.now());
        //安全盐
        String salt = SaltUtils.getSalt();
        register.setSalt(salt);
        register.setPassword(MD5Utils.encode(password + salt));
//        String pswd = passwordEncoder.encode(account);
//        System.out.println(MD5Utils.encode(pswd));

        save(register);


        return ResponseResult.okResult(200,"注册成功 请登录！");
    }
}
